home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 3 / Amiga Tools 3.iso / grafik / raytracing / rayshade-4.0.6.3 / inetray / stderr.c < prev    next >
C/C++ Source or Header  |  1993-08-17  |  6KB  |  274 lines

  1. /*======================================================================
  2.                     S T D E R R . C 
  3.                     doc: Mon Feb 24 16:24:35 1992
  4.                     dlm: Tue Aug 17 16:21:14 1993
  5.                     (c) 1992 ant@julia
  6.                     uE-Info: 92 0 T 0 0 72 10 2 8 ofnI
  7. ======================================================================*/
  8.  
  9. /*#define        VERBOSE            /* Babble */
  10.  
  11. #include    <stdio.h>
  12. #include    <syslog.h>
  13. #include    <signal.h>
  14. #include    <errno.h>
  15. #include    <fcntl.h>
  16. #include    <sys/types.h>
  17. #include    <sys/socket.h>
  18. #include    <sys/stat.h>
  19. #include    <sys/file.h>        /* SOLARIS */
  20. #include    "config.h"
  21. #include    "common.h"
  22. #ifdef NOSYSLOG_QUIRK
  23. #    include <string.h>
  24. #    include    <varargs.h>
  25. #    include <time.h>
  26. #endif
  27.  
  28. #define    READBUF    128            /* read buffer size */
  29.  
  30. extern int    errno;            /* for stderr2syslog */
  31. static int    ep[2];            /* error pipe */
  32. static char    redirOk = TRUE;        /* stderr redirection worked */
  33. #ifdef NOASYNCIO_QUIRK
  34. static char    *errFile;        /* name of error file */
  35. #endif
  36. #ifdef NOSYSLOG_QUIRK
  37. static char    syslogFile[STRLEN];    /* name of syslog file */
  38. static char    tag[STRLEN];        /* tag of syslog entry */
  39. void        noSyslogOpen();
  40. void        noSyslogClose();
  41. void        noSyslog();
  42. extern char     *sys_errlist[];
  43. #endif
  44.  
  45. /*----------------------------------------------------------------------*/
  46.  
  47. static void stderr2syslog()            /* stderr -> syslog */
  48. {
  49.     int    nByte,i;
  50.     char    buf[READBUF];
  51.     static char    line[READBUF];
  52.     static int    lPos = 0;
  53.  
  54.     if (!redirOk) {                /* testing */
  55.         nByte = read(ep[IN],buf,READBUF);
  56.         if (nByte != 1 || buf[0] != '?') {
  57.             SYSLOG(LOG_ERR,"Warning: Wrong stderr message!\n");
  58.         }
  59.         redirOk = TRUE;
  60.         signal(SIGIO,stderr2syslog);
  61.         return;
  62.     }
  63.  
  64.     do {                     /* read everything */
  65.         nByte = read(ep[IN],buf,READBUF);/* read (must be ready) */
  66.         if (nByte == 0) continue; 
  67.         if (nByte < 0) {
  68.             if (errno == EWOULDBLOCK) continue; 
  69.             SYSLOG(LOG_ERR,"stderr2syslog read: %m");
  70.         }
  71.         for (i=0; i<nByte; i++)    {    /* copy message part */
  72.             if (buf[i] == '\0')    /* skip \0 */
  73.                 continue;
  74.             if (buf[i] == '\n') {    /* terminate line */
  75.                 line[lPos] = '\0';
  76.                 SYSLOG(LOG_ERR,"%s",line);
  77.                 lPos = 0;
  78.                 continue;
  79.             }
  80.             line[lPos++] = buf[i];
  81.         }
  82.     } while (nByte > 0); 
  83.     signal(SIGIO,stderr2syslog);        /* reenable sysV signal */
  84. }
  85.  
  86. openStderr(prog)
  87. char *prog;
  88. {
  89. #ifdef NOASYNCIO_QUIRK
  90.  
  91.     errFile = tempnam(NULL,"inetray.");
  92.     ep[OUT] = open(errFile,O_WRONLY|O_CREAT,0666);
  93.     if (ep[OUT] < 0) {
  94.         SYSLOG(LOG_ERR,"open(%s): %m",errFile);
  95.         return -1;
  96.     }
  97. #else
  98.     int    pid;
  99.     
  100.     if (socketpair(PF_UNIX,SOCK_STREAM,0,ep) < 0) {    /* make pipe */
  101.         SYSLOG(LOG_ERR,"socketpair: %m");
  102.         return -1;
  103.     }
  104.     if (fcntl(ep[IN],F_SETFL,FASYNC|FNDELAY) < 0) { /* async mode */
  105.         SYSLOG(LOG_ERR,"fcntl F_SETFL: %m");
  106.         return -1;
  107.     }
  108.  
  109.     pid = getpid(0);                /* set prgp */
  110.     
  111.     if (fcntl(ep[IN],F_SETOWN,pid) < 0) {
  112.         SYSLOG(LOG_ERR,"fcntl F_SETOWN: %m");
  113.         return -1;
  114.     }
  115.     if ((int)signal(SIGIO,stderr2syslog) < 0) {    /* async read */
  116.         SYSLOG(LOG_ERR,"signal: %m");
  117.         return -1;
  118.     }
  119. #endif
  120. #ifdef VERBOSE
  121.     SYSLOG(LOG_NOTICE,"dup()ing...");
  122. #endif
  123.     if (dup2(ep[OUT],ERR) < 0) {            /* stderr */
  124.         SYSLOG(LOG_ERR,"dup2 ERR: %m");
  125.         return -1;
  126.     }
  127. #ifdef VERBOSE
  128.     SYSLOG(LOG_NOTICE,"CLOSELOG()");
  129. #endif
  130.     CLOSELOG();                    /* ultrix bug */
  131. #ifdef VERBOSE
  132.     SYSLOG(LOG_NOTICE,"OPENLOG(%s)",prog);
  133. #endif
  134.     OPENLOG(prog);
  135.  
  136. #ifndef NOASYNCIO_QUIRK                    /* check */
  137. #ifdef VERBOSE
  138.     SYSLOG(LOG_NOTICE,"Testing Stderr...");
  139. #endif
  140.     redirOk = FALSE;
  141.     fprintf(stderr,"?");
  142.     if (!redirOk) {
  143.         SYSLOG(LOG_ERR,"Warning: stderr is lost!\n");
  144.         redirOk = TRUE;
  145.     }
  146. #endif
  147. #ifdef VERBOSE
  148.     SYSLOG(LOG_NOTICE,"return 0");
  149. #endif
  150.     return 0;
  151. }
  152.  
  153. static unlinkEmpty(name)                /* unlink if empty */
  154. char *name;                        /* ignore errs */
  155. {
  156.     struct stat sBuf;
  157.  
  158.     if (name == NULL ||
  159.         stat(name,&sBuf) < 0) return FALSE;
  160.         
  161.     if (sBuf.st_size == 0) {            /* empty file */
  162.         unlink(name);
  163.         return FALSE;
  164.     } else {                    /* errors in file */
  165.         return TRUE;
  166.     }
  167. }
  168.     
  169. void closeStderr()
  170. {
  171. #ifdef NOASYNCIO_QUIRK
  172.     if (unlinkEmpty(errFile))
  173.         SYSLOG(LOG_ERR,"Errors in %s",errFile);
  174. #endif
  175. }
  176.  
  177. /*----------------------------------------------------------------------*/
  178.  
  179. #ifdef NOSYSLOG_QUIRK
  180. void noSyslogOpen(prog)                    /* try to open file */
  181. char *prog;                        /* no errmes */
  182. {
  183.     int fd;
  184.     
  185.     strncpy(syslogFile,_P_tmpdir,STRLEN);
  186.     strncat(syslogFile,NOSYSLOG,STRLEN-strlen(_P_tmpdir));
  187.     strncpy(tag,prog,STRLEN);
  188.  
  189.     if ((fd = open(syslogFile,O_WRONLY|O_APPEND)) < 0) {
  190.         if ((fd = creat(syslogFile,0666)) < 0 ||
  191.             fchmod(fd,0666) < 0) exit(1);
  192.     }
  193.     close(fd);
  194. }
  195.  
  196. void noSyslog(va_alist)                    /* write message */
  197. va_dcl                            /* %s %d %f %c %m ok */
  198. {                            /* no errmes */
  199.     va_list    av;
  200.     char    *fmt,msg[STRLEN];
  201.     int    i,fd,pri,timer;
  202.  
  203.     if ((fd = open(syslogFile,O_WRONLY|O_APPEND)) < 0)
  204.         return;
  205.  
  206.     timer = time(NULL);
  207.     strftime(msg,STRLEN,"%b %d %T ",localtime(&timer));/* date & time */
  208.     write(fd,msg,strlen(msg));
  209.         
  210.     sprintf(msg,"%s[%d]: ",tag,getpid());        /* tag[pid] */
  211.     write(fd,msg,strlen(msg));
  212.  
  213.     va_start(av);
  214.     pri = va_arg(av,int);                /* print priority */
  215.     switch (pri) {
  216. #ifdef LOG_EMERG
  217.         case LOG_EMERG: sprintf(msg,"%s: ","LOG_EMERG"); break;
  218. #endif
  219. #ifdef LOG_ALERT
  220.         case LOG_ALERT: sprintf(msg,"%s: ","LOG_ALERT"); break;
  221. #endif
  222. #ifdef LOG_CRIT
  223.         case LOG_CRIT: sprintf(msg,"%s: ","LOG_CRIT"); break;
  224. #endif
  225. #ifdef LOG_ERR
  226.         case LOG_ERR: sprintf(msg,"%s: ","LOG_ERR"); break;
  227. #endif
  228. #ifdef LOG_WARNING
  229.         case LOG_WARNING: sprintf(msg,"%s: ","LOG_WARNING"); break;
  230. #endif
  231. #ifdef LOG_NOTICE
  232.         case LOG_NOTICE: sprintf(msg,"%s: ","LOG_NOTICE"); break;
  233. #endif
  234. #ifdef LOG_INFO
  235.         case LOG_INFO: sprintf(msg,"%s: ","LOG_INFO"); break;
  236. #endif
  237. #ifdef LOG_DEBUG
  238.         case LOG_DEBUG: sprintf(msg,"%s: ","LOG_DEBUG"); break;
  239. #endif
  240.         default: sprintf(msg,"Priority <%d>: ",pri); break;
  241.     }
  242.     write(fd,msg,strlen(msg));
  243.     
  244.     fmt = va_arg(av,char *);            /* handle args */
  245.     
  246.     for (i=0; fmt[i]!='\0'; i++) {
  247.         if (fmt[i] != '%') {            /* normal char */
  248.             write(fd,&fmt[i],1);
  249.             continue;
  250.         }
  251.         i++;
  252.         switch (fmt[i]) {
  253.             case 'c': sprintf(msg,"%c",va_arg(av,char));
  254.                   break;
  255.             case 's': sprintf(msg,"%s",va_arg(av,char *));
  256.                   break;
  257.             case 'd': sprintf(msg,"%d",va_arg(av,long));
  258.                   break;
  259.             case 'f': sprintf(msg,"%f",va_arg(av,double));
  260.                   break;
  261.             case 'm': sprintf(msg,"%s",sys_errlist[errno]);
  262.                   break;
  263.             default:  sprintf(msg,"<%%%c skipped!>",fmt[i+1]);
  264.                   (void)va_arg(av,void *);
  265.                   break;
  266.         }
  267.         write(fd,msg,strlen(msg));
  268.     }
  269.     va_end(av);
  270.     write(fd,"\n",2);
  271.     close(fd);
  272. }
  273. #endif
  274.